---
title: Upgrading to v1
description: How to upgrade your existing Chakra UI projects to v1.0
---

Chakra UI v1.0 is focused on improving the ideas and concepts from v0.8 to make
it even easier to create, theme and extend components.

While there are quite a number of new features we've added, we focused on making
Chakra UI a stable base to build your own design systems on top of. In the end,
we want make you feel more confident using Chakra UI in production.

---

## Highlights

**Theming API:** Chakra UI now provides a new theming API which makes it easy to
style components and their modifiers (sizes, variants, and color scheme) from
your theme.

**Color mode improvement:** We've fixed the bugs related to Color mode and made
it possible to persist color mode, set initial color mode, and lock specific
components to a certain color mode.

**Better TypeScript support:** This means all components have very good
TypeScript support and most low-level components like `Box`, `Flex` will support
the `as` prop and types will be extracted properly.

**Theme-aware sx prop:** Just like `theme-ui`, we've added support for the `sx`
prop to help you add theme-aware styles directly on any Chakra component. This
is useful if you're not a fan of style props, and prefer passing all styles in
one object.

**Deprecated PseudoBox:** We've removed `PseudoBox` and merged all its props
with `Box` so you can use pseudo style props, like `_hover`, `_active` in any
Chakra components.

**Dropped Support of IE11:** We've dropped support of `IE11`
[reason](https://github.com/chakra-ui/chakra-ui/pull/2762)

---

## Upgrade steps

Here's a list of steps to migrate your project to v1. Don't worry if your styles
aren't exactly the same, this is to be expected and following these steps will
fix it.

### 1. Update your dependencies

- Install the `framer-motion` package. We use this to manage animations and
  transitions within components.

- Remove the `emotion-theming` package. As at emotion v11, `emotion-theming` has
  been removed and all it's functionality has been migrated to `@emotion/react`.

- Rename the `@emotion/core` package to `@emotion/react`. `@emotion/core` was
  recently changed to `@emotion/react` following the v11 release by the
  emotionjs team.

- Rename the `@chakra-ui/core` package to `@chakra-ui/react`.

- Update the `@emotion/styled` package to v11.

```diff
"dependencies": {
- "@chakra-ui/core": "^0.8.0",
+ "@chakra-ui/react": "^1.0.0",
  "framer-motion": "^4.0.0",
- "@emotion/core": "^10.0.10",
+ "@emotion/react": "^11.0.0",
  "@emotion/styled": "^11.0.0",
- "emotion-theming": "10.0.10"
}
```

> Please note that when using Chakra UI in a TypeScript project, a minimum
> TypeScript version of `3.8.0` is required.

#### Notes on Icons

Chakra moved all icons to a separate package `@chakra-ui/icons`. We recommend
using `react-icons` in your projects considering it has a robust set of icons.
However, you can still install this package.

### 2. Update the ThemeProvider

Swap out `ThemeProvider` with `ChakraProvider` to make setup cleaner.
`ChakraProvider` adds the following providers for you automatically:

- **ThemeProvider:** Provides the theming context for all components.
- **ColorModeProvider:** Provides color mode (light or dark) context to all
  components.
- **GlobalStyle**: Provides the global styles defined in `theme.styles.global`
  to your application.

Optionally via prop:

- **CSSReset**: To omit the recommended `CSSReset`, pass `resetCSS={false}`.
- **PortalManager:** Manages portals and nested portals without using `z-index`
  in your application. Pass the `portalZIndex` prop.

```diff
-  <ThemeProvider>
+    <ChakraProvider>
-     <CSSReset />
      <App />
+    </ChakraProvider>
-  </ThemeProvider>
```

### 3. Rename `variantColor` to `colorScheme`

Fire up your "Find and Replace" tool in VSCode or IntelliJ. Find `variantColor`
and replace with `colorScheme`.

> **Reason:** We renamed this prop to make it easier to understand that this
> prop represents a visual color scheme, not a css color attribute.

### 4. Update layout `size` prop

Change `size` prop to `width` or `w` and `height`, or `h`. If you'd like to use
only one prop to manage this, you can rename it to `boxSize`.

```diff
- <Box size="40px" />
+ <Box w="40px" h="40px" />
# or
+ <Box boxSize="40px" />
```

**We strongly recommend using the `width` and `height` props**

> **Reason:** We think the `size` prop should only be used for component size
> modifiers. The `size` prop has caused a lot of confusion in the past because,
> in some components (e.g. Button), it means the visual size and in others (e.g
> Box), it means **width and height**.

### 5. Replace elements

#### PseudoBox

`PseudoBox` is now deprecated and its props can now be directly applied to
`Box`. Replace all `PseudoBox` components with `Box`.

```diff
-   <PseudoBox
+   <Box
    >
-    <PseudoBox
+     <Box
        _hover={{ fontWeight: 'semibold' }}
        _groupHover={{ color: 'tomato' }}
      >
-      </PseudoBox>
+      </Box>
-    </PseudoBox>
+    </Box>
```

#### Callout

`Callout` is now deprecated and you can use an `Alert` instead.

```diff
-   <Callout
+   <Alert
      mt={4}
      w="90%"
      bg="black"
      variant="left-accent"
    >
-   </Callout>
+   </Alert>
```

### 6. Update theme breakpoints

**You may skip this if you didn't customize your breakpoints.**

To provide easier extensibility and typesafety, breakpoints should now be
created through `createBreakpoints` by passing an object:

```diff
+ import { extendTheme } from "@chakra-ui/react"
+ import { createBreakpoints } from "@chakra-ui/theme-tools"


+ const breakpoints = createBreakpoints({
+   sm: "30em",
+   md: "48em",
+   lg: "62em",
+   xl: "80em",
+ })


const overrides = {
- breakpoints: ["30em", "48em", "62em", "80em"]
+ breakpoints,
}

+ const customTheme = extendTheme(overrides)
```

**Please note that unless you plan overriding all components, `sm` to `xl` are
required.**

You may of course add for example `xxl` or other breakpoints in between -
`createBreakpoints` will sort in ascending order. It is adviseable to not mix
css units.

> **Reason:** Previously, breakpoints on a theme had to be an array with your
> breakpoints in ascending order which made it hard to reference which value was
> correlating to `md` etc. Also, you had to manually manipulate the array by
> defining properties on it, which was often overlooked and not typesafe.

### 7. ColorModeScript (optional)

**You can skip this if you are not already using the color mode feature.**

To keep color mode settings in sync across pages, add the `ColorModeScript`.

For exhaustive examples, please visit
[**Features > Color Mode # Add ColorModeScript**](/docs/features/color-mode#add-colormodescript).

---

## Component Updates

We've updated the API of some components to fix bugs, improve usability, types
and accessibility.

### Accordion

- Update all imports of `AccordionHeader` to `AccordionButton`. This is to
  remove the notion that it is a header when it is actually a button.

```diff
- import { AccordionHeader } from "@chakra-ui/react"
+ import { AccordionButton } from "@chakra-ui/react"
```

> WAI-ARIA guidelines require that accordion buttons be wrapped in the
> appropriate heading tag `h2-h6` based on the page heading flow.

We think the name `AccordionHeader` might mislead users to think we handle this
out of the box when we don't. Here's how to handle this:

```jsx live=false
<Accordion>
  <AccordionItem>
    <h3>
      <AccordionButton>This is the button</AccordionButton>
    </h3>
    <AccordionPanel>This is the content</AccordionPanel>
  </AccordionItem>
</Accordion>
```

- You can no longer use `AccordionItem` in isolation, it must be used within
  `Accordion`.

### AspectRatioBox

- Change all imports of `AspectRatioBox` to `AspectRatio`.

```diff
- import { AspectRatioBox } from "@chakra-ui/react"
+ import { AspectRatio } from "@chakra-ui/react"
```

### Breadcrumb

Removed support for the `addSeparator` prop.

### Button

- We've unified the usage of all icon props to only accept a React element.
  Update all icon names used in `leftIcon` or `rightIcon` to the equivalent icon
  React element.

> Replacement logic: If `leftIcon` is `email`, then replace it with
> `<EmailIcon/>` from Chakra.

```diff
import { PhoneIcon } from "@chakra-ui/icons"

- <Button leftIcon="phone">Call</Button>
+ <Button leftIcon={<PhoneIcon />}>Call</Button>
```

**This reduces the effort needed to use custom icons, eliminates TypeScript
errors, and reduces unused icons bloating your app.**

- Renamed `variantColor` to `colorScheme`

- Removed negative side margins on `leftIcon` and `rightIcon` elements. We
  believe the user should handle these side margins.
  [#1024](https://github.com/chakra-ui/chakra-ui/issues/1024)

### Checkbox

- Change `variantColor` to `colorScheme`

```diff
- <Checkbox variantColor="blue">Option</Checkbox>
+ <Checkbox colorScheme="blue">Option</Checkbox>
```

- Deprecated the `isFullWidth` prop. `Checkbox` now takes up the width of its
  parent by default.

- To allow for better checkbox group layout, the `CheckboxGroup` component no
  longer supports every style prop.

  You can now only pass `size`, `variant`, and `colorScheme` in addition to
  `CheckboxGroup`-specific props (`value`, `defaultValue`, and `onChange`).

```jsx live=false
// before
<CheckboxGroup isInline spacing="40px" defaultValue={["one", "two"]}>
  <Checkbox value="one">One</Checkbox>
  <Checkbox value="two">Two</Checkbox>
  <Checkbox value="three">Three</Checkbox>
</CheckboxGroup>

// after
<CheckboxGroup defaultValue={["one", "two"]}>
  <Stack spacing="40px">
    <Checkbox value="one">One</Checkbox>
    <Checkbox value="two">Two</Checkbox>
    <Checkbox value="three">Three</Checkbox>
  </Stack>
</CheckboxGroup>
```

> We believe a checkbox group's layout should be managed by your design
> requirements. The checkboxes can be grouped using `Stack`, placed in a grid
> using `SimpleGrid` or made to wrap automatically using `Wrap`.

### ColorMode

- Color mode now persists correctly when you refresh the page. All you need to
  do is add `ColorModeScript` script as the first child of `body`.

  Here's how to add it for Next.js:

```jsx live=false
// pages/_document.js
import { ColorModeScript } from "@chakra-ui/react"

export default class Document extends NextDocument {
  static getInitialProps(ctx) {
    return NextDocument.getInitialProps(ctx)
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          {/* 👇 Here's the script */}
          <ColorModeScript />
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
```

Here's how to add it for Gatsby:

## Changes

- The Gatsby plugin has been renamed from `gatsby-plugin-chakra-ui` to
  `@chakra-ui/gatsby-plugin`. Please make sure to have updated this when
  installing Chakra UI in your next Gatsby project.

```jsx live=false
// gatsby-ssr.js
export const onRenderBody = ({ setPreBodyComponents }) => {
  setPreBodyComponents([<ColorModeScript key="chakra-ui-no-flash" />])
}
```

You can also install the
[`@chakra-ui/gatsby-plugin`](https://www.npmjs.com/package/@chakra-ui/gatsby-plugin)
package which automatically configures `ColorModeScript` along with
`ChakraProvider`.

### Editable

The `onRequestEdit` prop has been renamed to `onEdit`. This applies to both the
prop passed to `Editable` as well as the prop in its render props.

### Icons

- Basic interface icons provided by Chakra have moved to the `@chakra-ui/icons`
  package. Replace all `<Icon name="..." />` elements imported from
  `@chakra-ui/react` with equivalent React elements imported from
  `@chakra-ui/icons`.

  > Replacement logic: If `<Icon name="search" />` is used, then replace it with
  > `<SearchIcon />` from Chakra icons package.

```diff
- import { Icon } from "@chakra-ui/react"
- <Icon name="search" />

+ import { SearchIcon } from "@chakra-ui/icons"
+ <SearchIcon />
```

Existing icons will appear as a question mark until refactored.

- We changed the way custom icons are created. Instead of adding custom icons to
  `theme` create your own icons using the `createIcon` utility:

```jsx live=false
import { createIcon } from "@chakra-ui/react"

export const UpDownIcon = createIcon({
  displayName: "UpDownIcon",
  viewBox: "-1 -1 9 11",
  d:
    "M 3.5 0L 3.98809 -0.569442L 3.5 -0.987808L 3.01191 -0.569442L 3.5 0ZM 3.5 9L 3.01191 9.56944L 3.5 9.98781L 3.98809 9.56944L 3.5 9ZM 0.488094 3.56944L 3.98809 0.569442L 3.01191 -0.569442L -0.488094 2.43056L 0.488094 3.56944ZM 3.01191 0.569442L 6.51191 3.56944L 7.48809 2.43056L 3.98809 -0.569442L 3.01191 0.569442ZM -0.488094 6.56944L 3.01191 9.56944L 3.98809 8.43056L 0.488094 5.43056L -0.488094 6.56944ZM 3.98809 9.56944L 7.48809 6.56944L 6.51191 5.43056L 3.01191 8.43056L 3.98809 9.56944Z",
})
```

As a convenience you can also import `createIcon` from the `icons` package along
with other icons:

```jsx live=false
import { createIcon, MoonIcon, SunIcon } from "@chakra-ui/icons"
```

### Icon Button

- We've unified the usage of all icon props to only accept a React element.
  Update all icon names used in `icon` to the equivalent icon React element.

> Replacement logic: If `icon` is `email`, then replace it with `<EmailIcon/>`
> from Chakra.

```diff
import { PhoneIcon } from "@chakra-ui/react"

- <IconButton icon="phone">Call</IconButton>
+ <IconButton icon={<PhoneIcon />}>Call</IconButton>
```

**This reduces the effort needed to use custom icons, eliminates TypeScript
errors, and reduces unused icons bloating your app.**

- Renamed `variantColor` to `colorScheme`.

### Skeleton

Renamed `colorStart` and `colorEnd` props to `startColor` and `endColor`
respectively.

### Image

Resolved SSR issue with Next.js. If you still run into issues, we recommend
using the `Img` component which is a regular `img` tag with support for Chakra
props.

### Input

When using `InputAddon`, you no longer need to pass border radius properties to
the `Input`. `InputGroup` will intelligently detect the addon and apply the
necessary border to the input.

### Link

Due to accessibility reasons, we've deprecated the `isDisabled` prop for `Link`.

### List

Renamed `stylePos` to `stylePosition`

### ListIcon

We deprecated the `icon` prop. To change the icon rendered, kindly use the `as`
prop instead.

### Stack

- To reduce the API surface area, we've deprecated the `isReversed` props in
  favor of the `direction` prop.

```diff
- <Stack isReversed>
+ <Stack direction="row-reverse">
    <Box />
    <Box />
  </Stack>
```

- Added support for responsive `direction` and `spacing` props.

```jsx live=false
<Stack spacing={["16px", "32px"]} direction={["column", "row"]}>
  <Box />
  <Box />
</Stack>
```

### Menu

- All popper related props that used to be passed to `MenuList` component,
  should now be passed to `Menu`.
- The `placement` prop has moved from `MenuList` to `Menu`.

### Modal

- Removed `addAriaLabels` and `formatIds` props in favor of passing a top-level
  `id` prop to the modal.

- Removed `preserveScrollBarGap` prop. We preserve scroll bar gap by default to
  prevent any layout shift.

- `ModalCloseButton` now reads the `onClose` action from the `Modal` context - 
  you no longer need to pass the `onClick` to it. Conversely, the `onClose` prop
  on `Modal` is now a required prop if you specify `ModalCloseButton`.

- Only pass `size` values defined in the components theme. Hard-coded values
  will be ignored. Update the styles in `theme.components.Modal` to reflect your
  custom values.

- You can now disable focus trap by passing `trapFocus={false}`.

- Modal comes with preset transitions to make it easy for you. You can remove
  any existing `Scale`, `ScaleFade` or `SlideFade` components.

```jsx live=false
// before
<SlideIn in={isOpen}>
  {(styles) => (
    <Modal onClose={onClose} isOpen>
      <ModalOverlay opacity={styles.opacity} />
      <ModalContent pb={5} {...styles}>
        <ModalHeader>Login now</ModalHeader>
        <ModalCloseButton />
        <ModalBody>
          <Lorem count={2} />
        </ModalBody>
      </ModalContent>
    </Modal>
  )}
</SlideIn>

// after
<Modal motionPreset="slideInBottom" onClose={onClose} isOpen={isOpen}>
  <ModalOverlay />
  <ModalContent pb={5}>
    <ModalHeader>Login now</ModalHeader>
    <ModalCloseButton />
    <ModalBody>
      <Lorem count={2} />
    </ModalBody>
  </ModalContent>
</Modal>
```

### Progress

Changed `color` prop to `colorScheme`.

```diff
- <Progress color="blue"/>
+ <Progress colorScheme="blue"/>
```

### CircularProgress

- `trackColor` prop now takes a specific theme color or a valid `css` color.
- Changed the `thickness` prop to point to an actual thickness value in `px`
  (e.g. `thickness={4}`)

```diff
- <CircularProgress value={59} size="100px" thickness={0.1} />
+ <CircularProgress value={59} size="100px" thickness={10} />
```

### Radio

- Changed `variantColor` prop to `colorScheme`.

```diff
- <Radio variantColor="blue">Option</Radio>
+ <Radio colorScheme="blue">Option</Radio>
```

- Deprecated the `isFullWidth` prop. The `Radio` takes up the width of its
  parent by default.

- Deprecated the `RadioButton` component. Use the `useRadio` hook to create
  custom radio buttons. Learn more about
  [creating custom radio buttons](/docs/form/radio#custom-radio-buttons).

- The `useRadio` hook is exported with state and focus management logic for use
  in creating tailor-made radio component for your application

### RadioGroup

- Deprecated the `isFullWidth` prop. The `RadioGroup` takes up the width of the
  parent by default.

- Deprecated the `RadioButtonGroup` component. Use the `useRadioGroup` hook to
  control a group of custom radio buttons. Learn more about
  [creating custom radio buttons](/docs/form/radio#custom-radio-buttons).

- To allow for better Radio group layout, the `RadioGroup` component no longer
  supports every style prop. You can only pass `size`, `variant`, and
  `colorScheme` in addition to `RadioGroup` props (`value`, `defaultValue`, and
  `onChange`).

```jsx live=false
// before
<RadioGroup isInline defaultValue="one">
  <Radio value="one">One</Radio>
  <Radio value="two">Two</Radio>
  <Radio value="three">Three</Radio>
</RadioGroup>

// after
<RadioGroup defaultValue="one">
  <Stack direction="row">
    <Radio value="one">One</Radio>
    <Radio value="two">Two</Radio>
    <Radio value="three">Three</Radio>
  </Stack>
</RadioGroup>
```

- The `onChange` callback now returns the selected `value` not the `event`.

```jsx live=false
const [value, setValue] = React.useState("one")

// before
<RadioGroup value={value} onChange={e => setValue(e.target.value)}>
  <Radio value="one">One</Radio>
  <Radio value="two">Two</Radio>
  <Radio value="three">Three</Radio>
</RadioGroup>

// after
<RadioGroup value={value} onChange={val => setValue(val)}>
  <Stack direction="row">
    <Radio value="one">One</Radio>
    <Radio value="two">Two</Radio>
    <Radio value="three">Three</Radio>
  </Stack>
</RadioGroup>
```

## Slider

- Update JSX structure: Wrap `SliderFilledTrack` with `SliderTrack`.

```jsx live=false
// before
<Slider defaultValue={30}>
  <SliderTrack />
  <SliderFilledTrack />
  <SliderThumb />
</Slider>

// after
<Slider defaultValue={30}>
  <SliderTrack>
    <SliderFilledTrack />
  </SliderTrack>
  <SliderThumb />
</Slider>
```

### Switch

Rename the `color` prop to `colorScheme`.

```diff
-  <Switch color="blue"/>
+  <Switch colorScheme="blue"/>
```

### Tabs

Change `variantColor` prop to `colorScheme`.

### Tags

- Change `variantColor` to `colorScheme`.

```diff
- <Tag variantColor="blue"/>
+ <Tag colorScheme="blue"/>
```

- Added support for `isDisabled` prop on the `TagCloseButton` component.

```jsx live=false
<Tag variant="solid" size="sm" colorScheme="cyan">
  <TagLabel>Tab Label</TagLabel>
  <TagCloseButton isDisabled />
</Tag>
```

- Default size was changed from `lg` to `md`.

### Toast

- Removed `react-spring` dependency in favor of `framer-motion`.
- Added support for duplicate toast prevention using `toast.isActive` method.
- Added support to programmatically close one or all toasts using `toast.close`
  or `toast.closeAll` methods.
- Added support to programmatically update a toast using `toast.update` method.
- Added support for `onCloseComplete` prop, which is a callback function that is
  invoked when the toast closes.

### Wrap (for `rc` versions)

- Children of `Wrap` must now be _wrapped_ in `WrapItem`. This makes it easy to
  customize the `WrapItem` using the `sx` prop.

```jsx live=false
// before
<Wrap spacing="30px">
  <Center w="180px" h="80px" bg="red.200">Box 1</Center>
  <Center w="180px" h="80px" bg="green.200">Box 2</Center>
  <Center w="180px" h="80px" bg="tomato">Box 3</Center>
</Wrap>

// after
<Wrap spacing="30px">
  <WrapItem>
    <Center w="180px" h="80px" bg="red.200">Box 1</Center>
  </WrapItem>
  <WrapItem>
    <Center w="180px" h="80px" bg="green.200">Box 2</Center>
  </WrapItem>
  <WrapItem>
    <Center w="180px" h="80px" bg="tomato">Box 3</Center>
  </WrapItem>
</Wrap>
```

### Transition Components

All transition components like `Collapse`, `Fade`, `SlideFade`, etc. use the
`in` prop to trigger its transition/animation, instead of `isOpen`. Change the
`isOpen` prop to `in`

### CSS Reset

- Removed the `config` prop, in favor of adding global styles to
  `theme.styles.global`.
- If you want to remove focus for non-keyboard interactions, install the
  `focus-visible` package.

```bash
yarn add focus-visible
# or
npm install focus-visible


# at the root of your application
import "focus-visible/dist/focus-visible"
```

### Hooks

- `useDisclosure` now accepts `object` instead of `boolean` as initial values.

```diff
- const { isOpen, onToggle } = useDisclosure(true);
+ const { isOpen, onToggle } = useDisclosure({defaultIsOpen: true});
```

**That's it! Welcome to Chakra UI v1 🥳.**

> If you still experience issues after migrating, feel free to create an issue
> or join our Discord chat here: https://discord.gg/dQHfcWF
